package run;

import processing.core.PApplet;
import processing.core.PImage;
import processing.core.PVector;

public class Mario {

	PVector pos;
	MarioGameEnv env;
	PImage marioImg;
	PApplet p;
	
	PImage[] runFrames = new PImage[3];
	
	PVector initPos;
	public Mario(PVector initPos, MarioGameEnv e, PApplet p) {
		pos = initPos;
		this.initPos = PVector.add(initPos, new PVector(0,0));
		env = e;
		marioImg = p.loadImage("MarioStanding.png");
		this.p = p;
		
		RIGHT_ON = false;
		LEFT_ON = false;
		
		runFrames[0] = p.loadImage("Mario-1.gif");
		runFrames[1] = p.loadImage("Mario-2.gif");
		runFrames[2] = p.loadImage("Mario-3.gif");
	}
	
	PVector vel = new PVector(0,0);
	
	private int run_state = 0;
	private boolean RIGHT_ON;
	private boolean LEFT_ON;
	
	public void draw(PApplet p) {
		
		if (vel.y < 0) {
			marioImg = p.loadImage("MarioJumping.png");
		}
		else if (RIGHT_ON) {
			vel.x = 4F;
			run_state = (++run_state) % 3;
			marioImg = runFrames[run_state];
		}
		else if (LEFT_ON) {
			vel.x = -4F;
			run_state = (++run_state) % 3;
			marioImg =runFrames[run_state];
		}
		else {
			vel.x -= 0.2 * vel.x;
			marioImg = p.loadImage("MarioStanding.png");
		}
		
		pos.add(vel);

		// run mario physics; let him drop to the ground unless colliding
		if (! isOnTopGround() && ! isUnderGround()) {	
//			PVector gravity = new PVector(0, 0.25F);
//			vel.add(gravity);
//			System.out.println(vel);
			
//			if ( ! env.pixelOccupied(  PVector.add(pos, vel) ))
//				vel.y += 0.25;
//			pos.add(new PVector(0,2));
			vel = new PVector(vel.x, vel.y + 1);
		}
		else {
			while (isUnderGround()) {
				pos.y--;
			}
			if (vel.y > 0) vel.y = 0;
		}			

		
//		System.out.println(pos + " " + vel);
		
		p.pushMatrix();
			p.translate(pos.x, pos.y);
//			p.fill(20,0,0,70);
//			p.rect(0,0, 20,22);
			
			if (vel.x < 0) {
				p.scale(-1,1);
				p.translate(-23,0);
			}
			p.scale(1.5F);
				
			p.image(marioImg, 0,0);
		p.popMatrix();
		
		
		revive();
	}

	private void revive() {
		if (env.outOfBounds(pos))
			pos = initPos;
	}

	synchronized public void updateEnv(MarioGameEnv e) {
		env = e;
	}
	
	private boolean isOnTopGround() {
		PVector lowerPt = PVector.add(pos, new PVector(5,23));
		p.pushMatrix();
//			p.stroke(0,200,0,100);
//			p.strokeWeight(2);
//			p.fill(0,200,0,100);
//			p.rect(lowerPt.x, lowerPt.y, 2, 2);
		p.popMatrix();
		
		return env.collidesWithObj(lowerPt) || env.pixelOccupied(PVector.add(lowerPt, new PVector(0,2)));
	}
	
	private boolean isUnderGround() {
		PVector lowerPt = PVector.add(pos, new PVector(5,24));
		p.pushMatrix();
//			p.stroke(0,200,0,100);
//			p.strokeWeight(2);
//			p.fill(0,200,0,100);
//			p.rect(lowerPt.x, lowerPt.y, 2, 2);
		p.popMatrix();
		
		return env.collidesWithObj(lowerPt);
	}


	public void right(boolean on) {
//		vel.x = 5F;
		RIGHT_ON = on;
	}

	public void left(boolean on) {
//		vel.x = -5F;
		LEFT_ON = on;
	}

	public void jump() {
		if (isOnTopGround() || isUnderGround())
			vel.y -= 10;
		marioImg = p.loadImage("MarioJumping.png");
	}
	
	public void reset() {
		PVector newpos = new PVector(300,100);
//		newpos.add(initPos);
		pos = newpos;
		System.out.println("reset " + pos);
		vel = new PVector(0,0);
	}
}
